#![allow(dead_code, mutable_transmutes, non_camel_case_types, non_snake_case, non_upper_case_globals, unused_assignments, unused_mut)]
extern "C" {
    fn malloc(_: libc::c_ulong) -> *mut libc::c_void;
    fn free(_: *mut libc::c_void);
    fn memcpy(
        _: *mut libc::c_void,
        _: *const libc::c_void,
        _: libc::c_ulong,
    ) -> *mut libc::c_void;
    fn memset(
        _: *mut libc::c_void,
        _: libc::c_int,
        _: libc::c_ulong,
    ) -> *mut libc::c_void;
    fn strcpy(_: *mut libc::c_char, _: *const libc::c_char) -> *mut libc::c_char;
    fn strlen(_: *const libc::c_char) -> libc::c_ulong;
    fn __assert_fail(
        __assertion: *const libc::c_char,
        __file: *const libc::c_char,
        __line: libc::c_uint,
        __function: *const libc::c_char,
    ) -> !;
}
pub type size_t = libc::c_ulong;
pub type BlockHeader = _BlockHeader;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _BlockHeader {
    pub magic_number: libc::c_uint,
    pub bytes: size_t,
}
static mut allocated_bytes: size_t = 0 as libc::c_int as size_t;
#[no_mangle]
pub static mut allocation_limit: libc::c_int = -(1 as libc::c_int);
extern "C" fn alloc_test_get_header(mut ptr: *mut libc::c_void) -> *mut BlockHeader {
    let mut result: *mut BlockHeader = std::ptr::null_mut();

    unsafe {
        result = (ptr as *mut BlockHeader).offset(-1);
        assert_eq!((*result).magic_number, 0x72ec82d2, "result->magic_number == ALLOC_TEST_MAGIC");
    }

    result
}
extern "C" fn alloc_test_overwrite(
    mut ptr: *mut libc::c_void,
    mut length: size_t,
    mut pattern: libc::c_uint,
) {
    let mut byte_ptr: *mut libc::c_uchar = ptr as *mut libc::c_uchar;
    let mut i: size_t = 0;

    while i < length {
        unsafe {
            let pattern_seq = (i & 3) as libc::c_int;
            let b = (pattern >> 8 * pattern_seq & 0xff) as libc::c_uchar;
            *byte_ptr.offset(i as isize) = b;
        }
        i = i.wrapping_add(1);
    }
}
#[no_mangle]
pub extern "C" fn alloc_test_malloc(mut bytes: size_t) -> *mut libc::c_void {
    let mut header: *mut BlockHeader = std::ptr::null_mut();
    let mut ptr: *mut libc::c_void = std::ptr::null_mut();

    unsafe {
        if allocation_limit == 0 {
            return std::ptr::null_mut();
        }

        header = malloc(
            (std::mem::size_of::<BlockHeader>() as libc::c_ulong).wrapping_add(bytes),
        ) as *mut BlockHeader;
        assert!(!header.is_null(), "malloc failed to allocate memory");
        let mut boxed_header = Box::from_raw(header);
        boxed_header.magic_number = 0x72ec82d2 as libc::c_int as libc::c_uint;
        boxed_header.bytes = bytes;
        ptr = header.offset(1) as *mut libc::c_void;
        alloc_test_overwrite(ptr, bytes, 0xbaadf00d);
        allocated_bytes = allocated_bytes.wrapping_add(bytes);
        if allocation_limit > 0 {
            allocation_limit -= 1;
        }
        header = Box::into_raw(boxed_header);
    }

    ptr
}
#[no_mangle]
pub extern "C" fn alloc_test_free(mut ptr: *mut libc::c_void) {
    if ptr.is_null() {
        return;
    }

    let mut header: *mut BlockHeader;
    let mut block_size: size_t;

    unsafe {
        header = alloc_test_get_header(ptr);
        block_size = (*header).bytes;
        assert!(allocated_bytes >= block_size, "allocated_bytes >= block_size");
        alloc_test_overwrite(ptr, (*header).bytes, 0xdeadbeef as libc::c_uint);
        (*header).magic_number = 0;
        free(header as *mut libc::c_void);
        allocated_bytes = allocated_bytes.wrapping_sub(block_size);
    }
}
#[no_mangle]
pub extern "C" fn alloc_test_realloc(
    mut ptr: *mut libc::c_void,
    mut bytes: size_t,
) -> *mut libc::c_void {
    let mut new_ptr: *mut libc::c_void = std::ptr::null_mut();
    let mut bytes_to_copy: size_t = 0;

    new_ptr = alloc_test_malloc(bytes);

    if new_ptr.is_null() {
        return std::ptr::null_mut();
    }

    if !ptr.is_null() {
        let mut header: *mut BlockHeader = std::ptr::null_mut();
        unsafe {
            header = alloc_test_get_header(ptr);
            bytes_to_copy = (*header).bytes;
        }

        if bytes_to_copy > bytes {
            bytes_to_copy = bytes;
        }

        unsafe {
            memcpy(new_ptr, ptr, bytes_to_copy);
            alloc_test_free(ptr);
        }
    }

    return new_ptr;
}
#[no_mangle]
pub extern "C" fn alloc_test_calloc(
    mut nmemb: size_t,
    mut bytes: size_t,
) -> *mut libc::c_void {
    let mut result: *mut libc::c_void = std::ptr::null_mut();
    let mut total_bytes: size_t = nmemb * bytes;

    unsafe {
        result = alloc_test_malloc(total_bytes);
        if result.is_null() {
            return std::ptr::null_mut();
        }
        memset(result, 0, total_bytes);
    }

    result
}
#[no_mangle]
pub extern "C" fn alloc_test_strdup(
    mut string: *const libc::c_char,
) -> *mut libc::c_char {
    let mut result: *mut libc::c_char = std::ptr::null_mut();

    unsafe {
        result = alloc_test_malloc(
            (strlen(string)).wrapping_add(1),
        ) as *mut libc::c_char;
        assert!(!result.is_null(), "Memory allocation failed");
        strcpy(result, string);
    }

    result
}
#[no_mangle]
pub extern "C" fn alloc_test_set_limit(mut alloc_count: libc::c_int) {
    assert!(alloc_count >= 0, "alloc_count must be non-negative");
    
    unsafe {
        allocation_limit = alloc_count;
    }
}
#[no_mangle]
pub extern "C" fn alloc_test_get_allocated() -> size_t {
    unsafe { allocated_bytes }
}
